package com.qeng.aiwanba.util;

import android.app.Activity;
import android.app.FragmentManager;
import android.app.FragmentTransaction;
import android.content.ClipboardManager;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.net.Uri;
import android.widget.PopupWindow;

import com.github.lzyzsd.jsbridge.BridgeHandler;
import com.github.lzyzsd.jsbridge.BridgeWebView;
import com.github.lzyzsd.jsbridge.CallBackFunction;
import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;
import com.qeng.aiwanba.R;
import com.qeng.aiwanba.activity.SubActivity;
import com.qeng.aiwanba.fragment.BaseFragment;
import com.qeng.aiwanba.model.AppData;
import com.qeng.aiwanba.net.QYHttpUtils;
import com.umeng.socialize.ShareAction;
import com.umeng.socialize.UMShareListener;
import com.umeng.socialize.bean.SHARE_MEDIA;
import com.umeng.socialize.media.UMImage;
import com.umeng.socialize.media.UMWeb;
import com.umeng.socialize.shareboard.ShareBoardConfig;
import com.umeng.socialize.shareboard.SnsPlatform;
import com.umeng.socialize.utils.ShareBoardlistener;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import java.io.File;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;

import cn.idianyun.streaming.DianyunSdk;


/**
 * Created by lixy on 17/3/10.
 * HostJsScope中需要被JS调用的函数，必须定义成public static，且必须包含WebView这个参数
 */

@NotProguard
public class MyBridgeUtil {
    private static MyBridgeUtil instance;

    public static MyBridgeUtil getInstance(){
        if(instance == null){
            instance = new MyBridgeUtil();
        }
        return instance;
    }

    public static void registerHandler(final BridgeWebView webView){
        register(webView,"JSADeviceInfo");
        register(webView,"getBuildVer");
        register(webView,"showToast");
        register(webView,"JSAAPI");
        register(webView,"JSAShare");
        register(webView,"JSAHeaderColor");
        register(webView,"JSASaveKey");
        register(webView,"JSAGetKeysAndValues");
        register(webView,"JSAGetAllKeys");
        register(webView,"JSAGetValue");
        register(webView,"JSARemoveKeysAndValues");
        register(webView,"JSARemoveKey");
        register(webView,"JSABackPage");
        register(webView,"JSAPageAppear");
        register(webView,"registerBlur");
        register(webView,"JSACopyText");
        register(webView,"JSARefreshHtml");
        register(webView,"JSASetItemNumber");
        register(webView,"JSAOpenPage");
        register(webView,"JSAOpenScheme");
        register(webView,"JSAOpenApp");
        register(webView,"JSADownloaderAddTask");
        register(webView,"JSADownloaderRemoveTask");
        register(webView,"JSADownloaderGetTask");
        register(webView,"JSADownloaderGetAllTask");
        register(webView,"JSADownloaderPauseTask");
        register(webView,"JSADownloaderContinueTask");
        register(webView,"JSADownloaderRetryTask");
        register(webView,"JSADownloaderGetAppInfo");
        register(webView,"JSADownloaderInstallApp");
        register(webView,"JSADownloaderEditAllState");
        register(webView,"JSAWechatPay");
        register(webView,"JSAAlipay");
        register(webView,"JSACheckPlayable");
//        register(webView,"JSARemovePlayableListener");
        register(webView,"JSAStartOnlinePlay");
        register(webView,"JSAGetOnlinePlayTime");
        register(webView,"JSADownloaderGetAppInfoList");
    }

    private static void register(final BridgeWebView webView, final String methodName){
        webView.registerHandler(methodName, new BridgeHandler() {

            @Override
            public void handler(String data, CallBackFunction function) {
//                Log.e("tag",methodName+" js data:"+data);
                reflectMethod(methodName,new Object[]{webView.getContext(),data,function});
            }
        });
    }

    private void JSADeviceInfo(Context context,String data,CallBackFunction function){
        JSONObject object = new JSONObject();
        try {
            object.put("model",DeviceUtil.deviceBrand()+DeviceUtil.deviceModel());
            object.put("os",DeviceUtil.deviceOs());
            object.put("udid",DeviceUtil.udid());
            object.put("appVer",Util.getVersion(context));
            object.put("buildVer",Util.getVersionCode(context));
            object.put("wifi_mac",DeviceUtil.deviceMac(context));
            object.put("phone_ip",DeviceUtil.getIPAddress(context));
            object.put("network_status",Util.getNetworkType(context));
            object.put("bundleId",Util.getPackageName(context));
        } catch (JSONException e) {
            e.printStackTrace();
        }
        function.onCallBack(object.toString());
    }

    private void getBuildVer(Context context,String data,CallBackFunction function){
        function.onCallBack(String.valueOf(Util.getVersionCode(context)));
    }

    private void JSAOpenScheme(Context context,String data,CallBackFunction function){
        if(Util.isWeixinAvilible(context)) {
            try {
                JSONObject object = new JSONObject(data);
                String weixinScheme = object.optString("scheme");
                Intent intent = new Intent("android.intent.action.VIEW",Uri.parse(weixinScheme));
                context.startActivity(intent);

            } catch (JSONException e) {
                e.printStackTrace();
            }
        }else{
            Util.showToast(context,context.getString(R.string.tip_uninstall_weixin));
        }
        function.onCallBack(null);
    }

    private void showToast(Context context,String data,CallBackFunction function){
        Util.showToast(context,data);
    }

    private void JSAAPI(Context context, String data, final CallBackFunction function){
        try {
            JSONObject object = new JSONObject(data);
            String url = object.optString("url");
            JSONObject params = object.optJSONObject("data");


            QYHttpUtils.doPost(context, url, toHashMap(params), new QYHttpUtils.RequestCallback<String>() {
                @Override
                public void success(String result) {
                    function.onCallBack(result);
                }

                @Override
                public void failure(Exception e) {
                    function.onCallBack(null);
                }
            });
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public static void JSAShare(final Context context,String data,final CallBackFunction function){
        try {
            JSONObject object = new JSONObject(data);
            final String webUrl = object.optString("shareUrl");
            final String icon = object.optString("icon");
            final String desc = object.optString("desc");
//            final String image = object.optString("image");
            final String title = object.optString("title");

            ShareBoardConfig config = new ShareBoardConfig();
            config.setOnDismissListener(new PopupWindow.OnDismissListener() {
                @Override
                public void onDismiss() {
                    try {
                        function.onCallBack(new JSONObject().put("code",-2).toString());
                    } catch (JSONException e) {
                        e.printStackTrace();
                    }
                }
            });
            new ShareAction((Activity) context)
                    .setDisplayList(SHARE_MEDIA.WEIXIN,SHARE_MEDIA.WEIXIN_CIRCLE,SHARE_MEDIA.SINA,SHARE_MEDIA.QQ,SHARE_MEDIA.QZONE,SHARE_MEDIA.WEIXIN_FAVORITE)
                    .setShareboardclickCallback(new ShareBoardlistener() {
                        @Override
                        public void onclick(SnsPlatform snsPlatform, SHARE_MEDIA share_media) {
                            UMImage umImage = new UMImage(context,icon);
                            UMWeb web = null;
                            if(!Util.isEmpty(webUrl)) {
                                web = new UMWeb(webUrl);
                                web.setThumb(umImage);
                                web.setDescription(desc);
                                web.setTitle(title);
                            }
                            ShareAction shareAction = new ShareAction((Activity) context);
                            if(web == null){
                                shareAction.withMedia(umImage);
                            }else{
                                shareAction.withMedia(web);
                            }
                            shareAction.setPlatform(share_media)
                            .setCallback(new UMShareListener() {
                                @Override
                                public void onStart(SHARE_MEDIA share_media) {

                                }

                                @Override
                                public void onResult(SHARE_MEDIA share_media) {
                                    try {
                                        function.onCallBack(new JSONObject().put("code",0).toString());
                                    } catch (JSONException e) {
                                        e.printStackTrace();
                                    }

                                }

                                @Override
                                public void onError(SHARE_MEDIA share_media, Throwable throwable) {
                                    try {
                                        function.onCallBack(new JSONObject().put("code",-1).toString());
                                    } catch (JSONException e) {
                                        e.printStackTrace();
                                    }
                                }

                                @Override
                                public void onCancel(SHARE_MEDIA share_media) {
                                    try {
                                        function.onCallBack(new JSONObject().put("code",-2).toString());
                                    } catch (JSONException e) {
                                        e.printStackTrace();
                                    }

                                }
                            })
                            .share();
                        }
                    })
                    .open(config);
        }catch (Exception e){
            e.printStackTrace();
        }
    }

    private void JSAHeaderColor(Context context,String data,CallBackFunction function){
    }

    private void JSASaveKey(Context context,String data,CallBackFunction function){
        try {
            JSONObject object = new JSONObject(data);
            String key = object.optString("key");
            String value = object.optString("object");
            boolean save = object.optBoolean("save");
            if(save){
                JsParamsUtil.saveSpParam(context,key,value);
            }else{
                JsParamsUtil.saveTempParam(key,value);
            }
        } catch (JSONException e) {
            e.printStackTrace();
        }
        function.onCallBack(null);
    }

    private void JSAGetKeysAndValues(Context context,String data,CallBackFunction function){
        try {
            JSONObject object = new JSONObject(data);
            boolean save = object.optBoolean("save",false);
            if(save) {
                String result  = Util.EscapeJavaScriptFunctionParameter(new JSONObject(JsParamsUtil.getSpParams(context)).toString());
                function.onCallBack(new JSONObject(JsParamsUtil.getSpParams(context)).toString());
            }else{
                function.onCallBack(new JSONObject(JsParamsUtil.getTempParams()).toString());
            }
        } catch (JSONException e) {
            e.printStackTrace();
        }
    }

    private void JSAGetAllKeys(Context context,String data,CallBackFunction function){
        JSONObject object = null;
        try {
            object = new JSONObject(data);
            boolean isTemp = object.optBoolean("save",false);
            if(!isTemp){
                function.onCallBack(new JSONArray(JsParamsUtil.getTempAllKeys(context).toArray()).toString());
            }else {
                function.onCallBack(new JSONArray(JsParamsUtil.getSpAllKeys(context).toArray()).toString());
            }
        } catch (JSONException e) {
            e.printStackTrace();
        }
    }

    private void JSAGetValue(Context context,String data,CallBackFunction function){
        JSONObject object = null;
        try {
            object = new JSONObject(data);
            String key = object.optString("key");
            boolean save = object.optBoolean("save");
            if(!save){
                function.onCallBack((String)JsParamsUtil.getTempByKey(key));
            }else{
                function.onCallBack((String)JsParamsUtil.getSpParamsByKey(context,key,""));
            }
        } catch (JSONException e) {
            e.printStackTrace();
        }
    }

    private void JSARemoveKeysAndValues(Context context,String data,CallBackFunction function){
        JSONObject object = null;
        try {
            object = new JSONObject(data);
            boolean save = object.optBoolean("save",false);
            if(save){
                JsParamsUtil.removeAllSpParams(context);
            }else{
                JsParamsUtil.removeAllTemp();
            }
            function.onCallBack(null);
        } catch (JSONException e) {
            e.printStackTrace();
        }
    }

    private void JSARemoveKey(Context context,String data,CallBackFunction function){
        JSONObject object = null;
        try {
            object = new JSONObject(data);
            String key = object.optString("key");
            boolean save = object.optBoolean("save");
            if(save){
                JsParamsUtil.removeSpParam(context,key);
            }else{
                JsParamsUtil.removeTempParam(key);
            }
            function.onCallBack(null);
        }catch (Exception e){

        }

    }

    private void JSAOpenPage(Context context,String data,CallBackFunction function){
        try {
            JSONObject object = new JSONObject(data);
            String url = object.optString("url");
            int type = object.optInt("type",4);
            switch (type){
                case 1:
                    //打开外链
                    startFragment(context,url);
                    break;
                case 2:
                    //用浏览器打开
                    context.startActivity(new Intent("android.intent.action.VIEW", Uri.parse(url)));
                    break;
                case 3:
                    //打开内链
                    startFragment(context,File.separator+url);
                    break;
                default:
                    //打开默认错误页
                    break;
            }
        } catch (JSONException e) {
            e.printStackTrace();
        }
        function.onCallBack(null);

    }

//    回退
    private void JSABackPage(Context context,String data,CallBackFunction function){
        if(ActivityManagerUtil.isSubActivity()) {
            FragmentManager fm = ((Activity) context).getFragmentManager();
            if (fm.getBackStackEntryCount() == 0) {
                ((Activity) context).finish();
            } else {
                fm.popBackStack();
            }
        }else{
            Util.keyBack(context);
        }
        function.onCallBack(null);
    }


//    页面失焦上报
    private void registerBlur(Context context,String data,CallBackFunction function){

    }

//    复制到黏贴版
    private void JSACopyText(Context context,String data,CallBackFunction function){
        ClipboardManager cm = (ClipboardManager)context.getSystemService(Context.CLIPBOARD_SERVICE);
        // 将文本内容放到系统剪贴板里。
        cm.setText(data);
        function.onCallBack(null);
    }

    private void JSARefreshHtml(Context context,String data,CallBackFunction function){

    }


//    底部消息显示
    private void JSASetItemNumber(Context context,String data,CallBackFunction function){

    }

    private void JSAOpenApp(Context context,String data,CallBackFunction function){
        if(data != null) {
            try {
                Intent intent = context.getPackageManager().getLaunchIntentForPackage(new JSONObject(data).optString("packageName"));
                context.startActivity(intent);
            } catch (Exception e) {
                e.printStackTrace();
                Util.showToast(context, "没有安装");
            }
        }else{
            Util.showToast(context, "包名为空，无法打开");
        }
        function.onCallBack(null);
    }

    private void JSADownloaderAddTask(Context context, String data, CallBackFunction function){
        AppData appData ;
        try {
            JSONObject object = new JSONObject(data);
            appData = new AppData(object.optString("packageName"),object.optString("data"),object.optString("url"));
            DownloadUtil.addDownloadInfo(context,appData,~0);
            function.onCallBack(null);
        } catch (JSONException e) {
            e.printStackTrace();
        }
    }

    private void JSADownloaderRemoveTask(Context context,String data,CallBackFunction function) {
        try {
            DownloadUtil.deleteDownload(context, new JSONObject(data).optString("packageName"));
        } catch (JSONException e) {
            e.printStackTrace();
        }
        function.onCallBack(null);
    }

    private void JSADownloaderGetTask(Context context,String data,CallBackFunction function){
        try {
            function.onCallBack(DownloadUtil.getDownloadTask(context,new JSONObject(data).optString("packageName")));
        } catch (JSONException e) {
            e.printStackTrace();
        }
    }

    private void JSADownloaderGetAppInfoList(Context context,String data,CallBackFunction function){
        JSONObject result = new JSONObject();
        try {
            JSONArray jsonArray = new JSONArray(data);
            for(int i=0;i<jsonArray.length();i++){
                String name = (String)jsonArray.get(i);
                result.put(name,DownloadUtil.getDownloadTask(context,name));
            }
            function.onCallBack(result.toString());
        } catch (JSONException e) {
            e.printStackTrace();
        }
    }


    private void JSADownloaderGetAllTask(Context context,String data,CallBackFunction function){
        function.onCallBack(DownloadUtil.getAllDownloadTask(context));
    }

    private void JSADownloaderPauseTask(Context context,String data,CallBackFunction function){

        try {
            DownloadUtil.pauseDownload(context,new JSONObject(data).optString("packageName"));
        } catch (JSONException e) {
            e.printStackTrace();
        }
        function.onCallBack(null);
    }

    private void JSADownloaderContinueTask(Context context,String data,CallBackFunction function){
        try {
            DownloadUtil.resumeDownload(context,new JSONObject(data).optString("packageName"));
        } catch (JSONException e) {
            e.printStackTrace();
        }
        function.onCallBack(null);
    }

    private void JSADownloaderRetryTask(Context context,String data,CallBackFunction function){
        try {
            DownloadUtil.restartDownload(context,new JSONObject(data).optString("packageName"));
        } catch (JSONException e) {
            e.printStackTrace();
        }
        function.onCallBack(null);
    }

    private void JSADownloaderGetAppInfo(Context context,String data,CallBackFunction function){
        PackageManager pckMan = context.getPackageManager();

        List<PackageInfo> packageInfo = pckMan.getInstalledPackages(0);

        try {
            String packageName = new JSONObject(data).optString("packageName");

            JSONObject object = null;

            for (PackageInfo pInfo : packageInfo) {
                if(pInfo.packageName.equals(packageName)){
                    try {
                        object = new JSONObject();
                        object.put("versionName",pInfo.versionName);
                        object.put("versionCode",pInfo.versionCode);
                        function.onCallBack(object.toString());
                    }catch (Exception e){
                        e.printStackTrace();
                        function.onCallBack(null);
                    }
                    return;
                }
            }
            if(object == null) {
                function.onCallBack(null);
            }
        }catch (Exception e){
            e.printStackTrace();
        }
    }

    private void JSADownloaderInstallApp(Context context,String data,CallBackFunction function){
        try {
            String packageName = new JSONObject(data).optString("packageName");

            String path = DownloadUtil.getPathByPackageName(context,packageName);

            Util.installApk(context,path);

        }catch (Exception e){
            e.printStackTrace();
        }

        function.onCallBack(null);
    }

    private void JSADownloaderEditAllState(Context context,String data,CallBackFunction function){
        try {
            DownloadUtil.editAllDownloadState(context,new JSONObject(data).optInt("state"));
        } catch (JSONException e) {
            e.printStackTrace();
        }
        function.onCallBack(null);
    }

    private void JSAWechatPay(Context context,String data,CallBackFunction function){
        PayUtil.wechatPay(context,data,function);
    }

    private void JSAAlipay(Context context,String data,CallBackFunction function){
        PayUtil.alipay(context,data,function);
    }


    private void JSACheckPlayable(Context context, String data, CallBackFunction function){
        List<Integer> mAdIds = new ArrayList<>();
        DianyunSdk.getInstance().registerPlayableListener(MyOnCheckPlayableListener.getInstance(context,function));
//
        Gson gson = new Gson();
        Type type = new TypeToken<Integer[]>(){}.getType();
        Integer[] array = gson.fromJson(data, type);
        mAdIds.addAll(Arrays.asList(array));
        //检查对应的试玩广告是否可玩，此方法会访问网络，通过注册的回调OnCheckPlayableListener返回
        DianyunSdk.getInstance().checkPlayable(mAdIds);
    }

//    private void JSARemovePlayableListener(Context context,String data,CallBackFunction function){
//        DianyunSdk.getInstance().unregisterPlayableListener(MyOnCheckPlayableListener.getInstance(function));
//        function.onCallBack(null);
//    }

    private void JSAStartOnlinePlay(Context context,String data,CallBackFunction function){
        try {
            try {
                JSONObject object = new JSONObject(data);
                Constants.onlinePlayApp = new AppData(object.optString("packageName"),object.getString("data"),object.getString("url"));
                Constants.onlinePlayApp.setSwId(object.optInt("id"));
                DianyunSdk.getInstance().launch((Activity) context, new MyDyOnlinePlayListener(context), object.optInt("id"), true);
                function.onCallBack(String.valueOf(Constants.ONLINE_PLAY_STATE_SUCC));
            } catch (Exception e) {
                e.printStackTrace();
            }
        } catch (UnsupportedOperationException e) {
            //集成方可自行处理异常，如果完成步骤4（即判断可试玩的时候才展示相应的广告），则不会抛出该异常，下一个异常也类似
            Util.showToast(context, "该设备不支持试玩");
            function.onCallBack(String.valueOf(Constants.ONLINE_PLAY_STATE_NOT_SUPPORT));
        } catch (IllegalStateException e) {
            Util.showToast(context, "未获取试玩信息或获取试玩信息失败");
            function.onCallBack(String.valueOf(Constants.ONLINE_PLAY_STATE_OTHER_ERROR));
        }
    }

    private void JSAGetOnlinePlayTime(Context context,String data,CallBackFunction function){
        function.onCallBack(String.valueOf(DianyunSdk.getInstance().getPlayDuration()));
    }

    private static Object reflectMethod(String methodName,Object[] arguments) {
        Method[] methods = MyBridgeUtil.class.getDeclaredMethods();//得到方法
        for (Method method : methods) {
            if (methodName.equals(method.getName())) {
                Object obj = MyBridgeUtil.getInstance();//获取到方法对象,假设方法的参数是一个int,String,method名为getAge
                //执行方法
                try {
                    return method.invoke(obj, arguments);
                } catch (IllegalAccessException e) {
                    e.printStackTrace();
                } catch (InvocationTargetException e) {
                    e.printStackTrace();
                }
                return null;
            }
        }
        return null;
    }


    public void startFragment(Context context,String url){
        if(ActivityManagerUtil.isSubActivity()) {
            FragmentManager fm = ((Activity) context).getFragmentManager();
            FragmentTransaction transaction = fm.beginTransaction();

            BaseFragment baseFragment = BaseFragment.newInstance(url);
            transaction.hide(Constants.topFrgment);
            transaction.add(R.id.sub_container, baseFragment);
            transaction.addToBackStack(null);
            transaction.commit();
            Constants.topFrgment = baseFragment;
        }else{
            context.startActivity(new Intent(context, SubActivity.class).putExtra("url",url));
        }
    }


    private static HashMap<String, String> toHashMap(JSONObject jsonObject)
    {
        HashMap<String, String> data = null;
        try {
            data = new HashMap<String, String>();
            // 将json字符串转换成jsonObject
            Iterator it = jsonObject.keys();
            // 遍历jsonObject数据，添加到Map对象
            while (it.hasNext())
            {
                String key = String.valueOf(it.next());
                String value = String.valueOf(jsonObject.get(key));
                data.put(key, value);
            }

        }catch (Exception e){
            e.printStackTrace();
        }
        return data;
    }


}
